<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Title</title>
	</head>
	<body>
		<canvas id="test"></canvas>
		<canvas id="result1"></canvas>
		<div onclick="showOriginal()">显示原图</div>
		<div onclick="reverseColor()">反色效果</div>
		<div onclick="removeColor()">去色效果</div>
		<div onclick="singleColor()">单色效果</div>
		<div onclick="chineseColor()">中国版画效果</div>
		<div onclick="gaussBlurColor()">高斯模糊效果</div>
		<div onclick="reliefColor()">浮雕效果</div>
		<div onclick="mosaicProcess()">马赛克效果</div>
		<script>
			var test = document.querySelector("#test"); // 方法一
			var test_1 = document.getElementById("test"); // 方法二
			console.log(test);
			console.log(test_1);

			window.onload = function() {
				var img = new Image();
				img.src = "user.jpg";
				// 加载完成图片之后才能够执行canvas的操作
				img.onload = function() {
					displayImage(img)
				}
				if (window.localStorage) {
					//设置本地存储
					localStorage.setItem("name", "Tom");
					localStorage.setItem("age", "20");
					//获取本地存储
					console.log(localStorage.getItem("name"));
					console.log(localStorage.getItem("age"));
					//删除单个缓存
					localStorage.removeItem("name");
					//消除所有缓存
					// localStorage.clear();
				}
			}

			var canvas = document.querySelector("#test");
			var canvas_result1 = document.querySelector("#result1")

			var cxt = canvas.getContext("2d");
			var cxt_result1 = canvas_result1.getContext("2d");

			function displayImage(img) {
				canvas.width = 293;
				canvas.height = 220;
				cxt.drawImage(img, 0, 0, 293, 220);

				var imageDt = cxt.getImageData(0, 0, canvas.width, canvas.height);
				console.log("imageDt", imageDt)
				localStorage.setItem("imageData", imageDt);

				canvas_result1.width = 293;
				canvas_result1.height = 220;
				reverseColor()
			}

			//显示原图
			function showOriginal() {
				var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
				cxt_result1.putImageData(imageData, 0, 0);
			}
			//反色（负片）效果
			function reverseColor(imageData) {
				var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
				console.log("reverseColor-imageData", imageData)
				var imageData_length = imageData.data.length / 4;
				// 解析之后进行算法运算
				for (var i = 0; i < imageData_length; i++) {
					imageData.data[i * 4] = 255 - imageData.data[i * 4];
					imageData.data[i * 4 + 1] = 255 - imageData.data[i * 4 + 1];
					imageData.data[i * 4 + 2] = 255 - imageData.data[i * 4 + 2];
				}
				cxt_result1.putImageData(imageData, 0, 0);
			}

			//去色效果
			function removeColor() {
				var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
				var imageData_length = imageData.data.length / 4;
				// 解析之后进行算法运算
				for (var i = 0; i < imageData_length; i++) {
					var red = imageData.data[i * 4];
					var green = imageData.data[i * 4 + 1];
					var blue = imageData.data[i * 4 + 2];
					var gray = 0.3 * red + 0.59 * green + 0.11 * blue;
					imageData.data[i * 4] = gray;
					imageData.data[i * 4 + 1] = gray;
					imageData.data[i * 4 + 2] = gray;
				}
				cxt_result1.putImageData(imageData, 0, 0);
			}

			//单色效果
			function singleColor() {
				var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
				var imageData_length = imageData.data.length / 4;
				// 解析之后进行算法运算
				for (var i = 0; i < imageData_length; i++) {
					imageData.data[i * 4 + 1] = 0;
					imageData.data[i * 4 + 2] = 0;
				}
				cxt_result1.putImageData(imageData, 0, 0);
			}

			//中国版画效果
			function chineseColor() {
				var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
				var imageData_length = imageData.data.length / 4;
				// 解析之后进行算法运算
				for (var i = 0; i < imageData_length; i++) {
					var red = imageData.data[i * 4];
					var green = imageData.data[i * 4 + 1];
					var blue = imageData.data[i * 4 + 2];
					var gray = 0.3 * red + 0.59 * green + 0.11 * blue;
					var new_black;
					if (gray > 126) {
						new_black = 255;
					} else {
						new_black = 0;
					}
					imageData.data[i * 4] = new_black;
					imageData.data[i * 4 + 1] = new_black;
					imageData.data[i * 4 + 2] = new_black;
				}
				cxt_result1.putImageData(imageData, 0, 0);
			}

			function gaussBlurColor() {
				var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
				imageData = gaussBlur(imageData)
				cxt_result1.putImageData(imageData, 0, 0);
			}
			//高斯模糊效果
			function gaussBlur(imgData) {
				console.log(imgData);
				var pixes = imgData.data;
				var width = imgData.width;
				var height = imgData.height;
				var gaussMatrix = [],
					gaussSum = 0,
					x, y,
					r, g, b, a,
					i, j, k, len;

				var radius = 30;
				var sigma = 5;

				a = 1 / (Math.sqrt(2 * Math.PI) * sigma);
				b = -1 / (2 * sigma * sigma);
				//生成高斯矩阵
				for (i = 0, x = -radius; x <= radius; x++, i++) {
					g = a * Math.exp(b * x * x);
					gaussMatrix[i] = g;
					gaussSum += g;

				}
				//归一化, 保证高斯矩阵的值在[0,1]之间
				for (i = 0, len = gaussMatrix.length; i < len; i++) {
					gaussMatrix[i] /= gaussSum;
				}
				//x 方向一维高斯运算
				for (y = 0; y < height; y++) {
					for (x = 0; x < width; x++) {
						r = g = b = a = 0;
						gaussSum = 0;
						for (j = -radius; j <= radius; j++) {
							k = x + j;
							if (k >= 0 && k < width) { //确保 k 没超出 x 的范围
								//r,g,b,a 四个一组
								i = (y * width + k) * 4;
								r += pixes[i] * gaussMatrix[j + radius];
								g += pixes[i + 1] * gaussMatrix[j + radius];
								b += pixes[i + 2] * gaussMatrix[j + radius];
								// a += pixes[i + 3] * gaussMatrix[j];
								gaussSum += gaussMatrix[j + radius];
							}
						}
						i = (y * width + x) * 4;
						// 除以 gaussSum 是为了消除处于边缘的像素, 高斯运算不足的问题
						// console.log(gaussSum)
						pixes[i] = r / gaussSum;
						pixes[i + 1] = g / gaussSum;
						pixes[i + 2] = b / gaussSum;
						// pixes[i + 3] = a ;
					}
				}
				//y 方向一维高斯运算
				for (x = 0; x < width; x++) {
					for (y = 0; y < height; y++) {
						r = g = b = a = 0;
						gaussSum = 0;
						for (j = -radius; j <= radius; j++) {
							k = y + j;
							if (k >= 0 && k < height) { //确保 k 没超出 y 的范围
								i = (k * width + x) * 4;
								r += pixes[i] * gaussMatrix[j + radius];
								g += pixes[i + 1] * gaussMatrix[j + radius];
								b += pixes[i + 2] * gaussMatrix[j + radius];
								// a += pixes[i + 3] * gaussMatrix[j];
								gaussSum += gaussMatrix[j + radius];
							}
						}
						i = (y * width + x) * 4;
						pixes[i] = r / gaussSum;
						pixes[i + 1] = g / gaussSum;
						pixes[i + 2] = b / gaussSum;
					}
				}
				console.log(imgData);
				return imgData;
			}

			function reliefColor() {
				var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
				imageData = reliefProcess(cxt, imageData)
				cxt_result1.putImageData(imageData, 0, 0);
			}

			//浮雕效果与刻雕效果
			function reliefProcess(context, canvasData) {
				console.log("Canvas Filter - relief process");
				var tempCanvasData = this.copyImageData(context, canvasData);
				for (var x = 1; x < tempCanvasData.width - 1; x++) {
					for (var y = 1; y < tempCanvasData.height - 1; y++) {

						// Index of the pixel in the array    
						var idx = (x + y * tempCanvasData.width) * 4;
						var bidx = ((x - 1) + y * tempCanvasData.width) * 4;
						var aidx = ((x + 1) + y * tempCanvasData.width) * 4;

						// calculate new RGB value
						var nr = tempCanvasData.data[aidx + 0] - tempCanvasData.data[bidx + 0] + 128;
						var ng = tempCanvasData.data[aidx + 1] - tempCanvasData.data[bidx + 1] + 128;
						var nb = tempCanvasData.data[aidx + 2] - tempCanvasData.data[bidx + 2] + 128;
						nr = (nr < 0) ? 0 : ((nr > 255) ? 255 : nr);
						ng = (ng < 0) ? 0 : ((ng > 255) ? 255 : ng);
						nb = (nb < 0) ? 0 : ((nb > 255) ? 255 : nb);

						// assign new pixel value    
						canvasData.data[idx + 0] = nr; // Red channel    
						canvasData.data[idx + 1] = ng; // Green channel    
						canvasData.data[idx + 2] = nb; // Blue channel    
						canvasData.data[idx + 3] = 255; // Alpha channel    
					}
				}
				return tempCanvasData
			}

			function copyImageData(context, src) {
				var dst = context.createImageData(src.width, src.height);
				dst.data.set(src.data);
				return dst;
			}
			////马赛克图片效果- 方法一
			function mosaicProcess() {
				var tmpImageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
				var tmpPixelData = tmpImageData.data;

				var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
				var pixelData = imageData.data;

				var size = 5;
				var totalnum = size * size;
				for (var i = 0; i < canvas.height; i += size)
					for (var j = 0; j < canvas.width; j += size) {
						var totalr = 0,
							totalg = 0,
							totalb = 0;
						for (var dx = 0; dx < size; dx++)
							for (var dy = 0; dy < size; dy++) {
								var x = i + dx;
								var y = j + dy;
								var p = x * canvas.width + y;
								totalr += tmpPixelData[p * 4 + 0];
								totalg += tmpPixelData[p * 4 + 1];
								totalb += tmpPixelData[p * 4 + 2];
							}
						var p = i * canvas.width + j;
						var resr = totalr / totalnum;
						var resg = totalg / totalnum;
						var resb = totalb / totalnum;
						for (var dx = 0; dx < size; dx++)
							for (var dy = 0; dy < size; dy++) {
								var x = i + dx;
								var y = j + dy;
								var p = x * canvas.width + y;
								pixelData[p * 4 + 0] = resr;
								pixelData[p * 4 + 1] = resg;
								pixelData[p * 4 + 2] = resb;
							}
					}
				cxt_result1.putImageData(imageData, 0, 0);
			}
			//马赛克图片效果 -方法二
			function mosaicProcess1() {
				var size = 5;
				//获取老图所有像素点
				var oldImg = cxt.getImageData(0, 0, canvas.width, canvas.height);
				//创建新图像素对象
				var newImg = cxt.createImageData(canvas.width, canvas.height)
				for (var i = 0; i < oldImg.width; i++) {
					for (var j = 0; j < oldImg.height; j++) {
						//从5*5中获取单个像素信息
						var color = getPxInfo(oldImg, Math.floor(i * size + Math.random() * size),
							Math.floor(j * size + Math.random() * size))
						//写入单个像素信息
						for (var a = 0; a < size; a++) {
							for (var b = 0; b < size; b++) {
								setPxInfo(newImg, i * size + a, j * size + b, color);
							}
						}
					}
				}
				cxt_result1.putImageData(newImg, 0, 0);
			}
			//读取单个像素信息
			function getPxInfo(imgDate, x, y) {
				var colorArr = [];
				var width = imgDate.width;
				colorArr[0] = imgDate.data[(width * y + x) * 4 + 0]
				colorArr[1] = imgDate.data[(width * y + x) * 4 + 1]
				colorArr[2] = imgDate.data[(width * y + x) * 4 + 2]
				colorArr[3] = imgDate.data[(width * y + x) * 4 + 3]
				return colorArr;
			}
			//写入单个像素信息
			function setPxInfo(imgDate, x, y, colors) {
				//（x,y） 之前有多少个像素点 == width*y + x
				var width = imgDate.width;
				imgDate.data[(width * y + x) * 4 + 0] = colors[0];
				imgDate.data[(width * y + x) * 4 + 1] = colors[1];
				imgDate.data[(width * y + x) * 4 + 2] = colors[2];
				imgDate.data[(width * y + x) * 4 + 3] = colors[3];
			}
		</script>
	</body>
</html>
